<script setup>
/**
 * 导入 bpmn-js 和 bpmn-js-properties-panel 所需的样式文件。
 *
 * 该代码块主要用于加载 bpmn-js 及其属性面板相关的 CSS 样式资源，
 * 确保在使用 bpmn-js 渲染流程图时，界面能够正确显示所需的视觉效果。
 *
 * 样式文件说明：
 * - `diagram-js.css`: 提供基础的流程图渲染样式。
 * - `bpmn.css`: 包含 BPMN 图形元素的基本样式。
 * - `bpmn-codes.css`: 定义 BPMN 图形中使用的编码样式。
 * - `bpmn-embedded.css`: 针对嵌入式 BPMN 图形的样式优化。
 * - `bpmn-js-properties-panel.css`: 提供属性面板的样式支持。
 */
import 'bpmn-js/dist/assets/diagram-js.css';
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css';
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css';
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css';
import '@bpmn-io/properties-panel/dist/assets/properties-panel.css';

/**
 * 从 bpmn-js-properties-panel 包中引入模块，用于支持属性面板功能。
 */
import {
  BpmnPropertiesPanelModule,
  BpmnPropertiesProviderModule,
  CamundaPlatformPropertiesProviderModule
} from 'bpmn-js-properties-panel';

/**
 * 引入 BpmnModeler 类，用于创建和操作 BPMN 图表。
 */
import BpmnModeler from 'bpmn-js/lib/Modeler';
import BpmnViewer from 'bpmn-js/lib/Viewer';

/**
 * 引入 Camunda Moddle 描述符，用于扩展 BPMN 模型以支持 Camunda 特性。
 */
// import CamundaBpmnModdle from 'camunda-bpmn-moddle/resources/camunda.json';

/**
 * 从 Vue 中引入生命周期钩子和响应式引用。
 */
import { onMounted, ref } from 'vue';
import customTranslate from './translations';
import camundaModdleDescriptor from './camundaDescriptor.json';

const emits = defineEmits(['onSave']);
const props = defineProps({
  xmlStr: String,
  isViewer: {
    type: Boolean,
    default: false
  }
});

/**
 * 定义 canvasRef，用于引用 BPMN 图表的容器 DOM 元素。
 */
const canvasRef = ref(null);

/**
 * 定义 propertiesPanelRef，用于引用属性面板的容器 DOM 元素。
 */
const propertiesPanelRef = ref(null);

const modeler = ref(null);
const modelerView = ref(null);

onMounted(() => {
  init();
});

/**
 * 初始化
 * */
function init() {
  if (canvasRef.value && propertiesPanelRef.value) {
    if (props.isViewer) {
      modelerView.value = new BpmnViewer({ container: canvasRef.value });
      // 导入 BPMN XML 字符串并处理成功后的逻辑。
      modelerView.value.importXML(props.xmlStr).then(() => {
        // 成功后操作（此处可添加具体逻辑）。
        // 如果是查看模式，则禁用编辑功能
        modelerView.value.get('canvas').zoom('fit-viewport');
      });
    } else {
      // 初始化 BpmnModeler 实例，配置容器、属性面板和扩展模块。
      modeler.value = new BpmnModeler({
        container: canvasRef.value,
        propertiesPanel: {
          parent: propertiesPanelRef.value
        },
        additionalModules: [
          BpmnPropertiesPanelModule,
          BpmnPropertiesProviderModule,
          CamundaPlatformPropertiesProviderModule,
          {
            //汉化
            translate: ['value', customTranslate]
          }
          // {
          //   __init__: ["customPropertiesProvider"],
          //   customPropertiesProvider: ["type", PaletteProvider]
          // }
        ],
        moddleExtensions: {
          camunda: camundaModdleDescriptor
        }
      });

      // 导入 BPMN XML 字符串并处理成功后的逻辑。
      modeler.value.importXML(props.xmlStr).then(() => {
        // 成功后操作（此处可添加具体逻辑）。
      });

      const EventBus = modeler.value.get('eventBus');
      EventBus.on('element.click', function (eventObj) {
        console.log(eventObj);
      });
    }
  }
}

/**
 * 异步保存函数
 * 该函数负责将模型编辑器中的XML数据保存到服务器
 */
async function onSave() {
  // 定义 processXmlParam，允许为 string 或 undefined
  let processXmlParam;

  try {
    // 保存逻辑：获取格式化后的XML字符串
    const { xml } = (await modeler.value?.saveXML({ format: true })) || {};
    if (xml !== undefined) {
      processXmlParam = xml; // 如果xml存在，则赋值
    } else {
      processXmlParam = ''; // 如果xml不存在，设置为空字符串
    }

    // 调用接口保存XML
    const result = {
      processKey: props.xmlStr,
      processXml: processXmlParam || '' // 确保传递的参数为字符串
    };
    emits('onSave', result);
    return result;
  } catch (error) {
    // 处理异常
    let errorMessage = '未知错误';
    if (error instanceof Error) {
      errorMessage = error.message;
    }
    // 显示错误消息
    console.log(`保存失败: ${errorMessage || '未知错误'}`);
  }
}

defineExpose({
  onSave
});
</script>

<template>
  <div class="bpmn-container">
    <!-- BPMN 图表的主画布区域 -->
    <div ref="canvasRef" class="canvas" />
    <!-- 属性面板区域 -->
    <div ref="propertiesPanelRef" class="properties-panel" />
  </div>
</template>

<style scoped>
.bpmn-container {
  display: flex;
  height: 100%;
}

.canvas {
  flex: 3; /* 占据 3/4 的宽度 */
  border: 1px solid #ccc;
}

.properties-panel {
  flex: 1; /* 占据 1/4 的宽度 */
  border-left: 1px solid #ccc; /* 左侧边框分隔画布和属性面板 */
  overflow-y: auto; /* 支持垂直滚动 */
}
</style>
